package com.study.shiro;


import com.study.entity.SysUserEntity;
import com.study.dao.SysUserDao;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * 认证
 */
@Component
public class UserRealm extends AuthorizingRealm {
    @Resource
    private SysUserDao sysUserDao;

    /**
     * 授权(验证权限时调用)  身份认证。即登录通过账号和密码验证登陆人的身份信息。
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取当前登录的用户
        SysUserEntity user = (SysUserEntity)principals.getPrimaryPrincipal();
        Long userId = user.getUserId();
        //用户权限列表
        Set<String> permsSet = new HashSet<>();
        String perms = sysUserDao.queryAllPerms(userId);
        permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //添加角色
        //info.addRole(user.getRole());
        //添加权限
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证(登录时调用)  权限认证，即登录过后，每个身份不一定，对应的所能看的页面也不一样。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
        String name = token.getUsername();
        //查询用户信息
        SysUserEntity user = sysUserDao.selectOne(token.getUsername());
        if(user == null) {
            return null;
        }
//        String credentials = ShiroUtils.sha256(password, user.getSalt());
//        token.setPassword(credentials.toCharArray());
//        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), getName());

        System.out.println("user:" + user.toString());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), // 加盐
                getName());

        return info;
    }


    @Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
		shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
        // 散列的次数
		shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
        // storedCredentialsHexEncoded默认是true，此时用的是密码加密用的是Hex编码；false时用Base64编码
        shaCredentialsMatcher.setStoredCredentialsHexEncoded(true);
		super.setCredentialsMatcher(shaCredentialsMatcher);
	}
}
